<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>node_modules/egg-core/lib/egg.js - Documentation</title>

    <script src="scripts/prettify/prettify.js"></script>
    <script src="scripts/prettify/lang-css.js"></script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/ionicons.min.css">
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>

<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
  <div class="navicon"></div>
</label>

<label for="nav-trigger" class="overlay"></label>

<nav>
    <h2><a href="index.html">Home</a></h2>
  <h3>Egg</h3>
  <ul>
    <li>
      <a href="Egg.html">Egg</a>
      <a href="Application.html">Application</a>
      <a href="Context.html">Context</a>
      <a href="Request.html">Request</a>
      <a href="Response.html">Response</a>
    </li>
  </ul>
  <h3>Classes</h3><ul><li><a href="Agent.html">Agent</a><ul class='members'><li data-type='member'><a href="Agent.html#coreLogger">coreLogger</a></li><li data-type='member'><a href="Agent.html#env">env</a></li><li data-type='member'><a href="Agent.html#httpclient">httpclient</a></li><li data-type='member'><a href="Agent.html#logger">logger</a></li><li data-type='member'><a href="Agent.html#loggers">loggers</a></li><li data-type='member'><a href="Agent.html#messenger">messenger</a></li><li data-type='member'><a href="Agent.html#proxy">proxy</a></li><li data-type='member'><a href="Agent.html#addSingleton">addSingleton()</a></li><li data-type='member'><a href="Agent.html#cluster">cluster()</a></li><li data-type='member'><a href="Agent.html#curl">curl()</a></li><li data-type='member'><a href="Agent.html#getLogger">getLogger()</a></li><li data-type='member'><a href="Agent.html#inspect">inspect()</a></li></ul></li><li><a href="AgentWorkerLoader.html">AgentWorkerLoader</a><ul class='members'><li data-type='member'><a href="AgentWorkerLoader.html#loadConfig">loadConfig()</a></li></ul></li><li><a href="AppInfo.html">AppInfo</a><ul class='members'><li data-type='member'><a href="AppInfo.html#baseDir">baseDir</a></li><li data-type='member'><a href="AppInfo.html#env">env</a></li><li data-type='member'><a href="AppInfo.html#HOME">HOME</a></li><li data-type='member'><a href="AppInfo.html#name">name</a></li><li data-type='member'><a href="AppInfo.html#pkg">pkg</a></li><li data-type='member'><a href="AppInfo.html#root">root</a></li><li data-type='member'><a href="AppInfo.html#scope">scope</a></li></ul></li><li><a href="Application.html">Application</a><ul class='members'><li data-type='member'><a href="Application.html#coreLogger">coreLogger</a></li><li data-type='member'><a href="Application.html#createAnonymousContext">createAnonymousContext</a></li><li data-type='member'><a href="Application.html#env">env</a></li><li data-type='member'><a href="Application.html#Helper">Helper</a></li><li data-type='member'><a href="Application.html#httpclient">httpclient</a></li><li data-type='member'><a href="Application.html#keys">keys</a></li><li data-type='member'><a href="Application.html#locals">locals</a></li><li data-type='member'><a href="Application.html#logger">logger</a></li><li data-type='member'><a href="Application.html#loggers">loggers</a></li><li data-type='member'><a href="Application.html#messenger">messenger</a></li><li data-type='member'><a href="Application.html#proxy">proxy</a></li><li data-type='member'><a href="Application.html#view">view</a></li><li data-type='member'><a href="Application.html#addSingleton">addSingleton()</a></li><li data-type='member'><a href="Application.html#cluster">cluster()</a></li><li data-type='member'><a href="Application.html#createContext">createContext()</a></li><li data-type='member'><a href="Application.html#curl">curl()</a></li><li data-type='member'><a href="Application.html#getLogger">getLogger()</a></li><li data-type='member'><a href="Application.html#inspect">inspect()</a></li><li data-type='member'><a href="Application.html#runInBackground">runInBackground()</a></li></ul></li><li><a href="AppWorkerLoader.html">AppWorkerLoader</a><ul class='members'><li data-type='member'><a href="AppWorkerLoader.html#load">load()</a></li><li data-type='member'><a href="AppWorkerLoader.html#loadConfig">loadConfig()</a></li></ul></li><li><a href="global.html#BaseContextClass">BaseContextClass</a><ul class='members'><li data-type='member'><a href="global.html#BaseContextClass#app">app</a></li><li data-type='member'><a href="global.html#BaseContextClass#config">config</a></li><li data-type='member'><a href="global.html#BaseContextClass#ctx">ctx</a></li><li data-type='member'><a href="global.html#BaseContextClass#service">service</a></li></ul></li><li><a href="BaseContextLogger.html">BaseContextLogger</a><ul class='members'><li data-type='member'><a href="BaseContextLogger.html#ctx">ctx</a></li><li data-type='member'><a href="BaseContextLogger.html#debug">debug</a></li><li data-type='member'><a href="BaseContextLogger.html#error">error</a></li><li data-type='member'><a href="BaseContextLogger.html#info">info</a></li><li data-type='member'><a href="BaseContextLogger.html#warn">warn</a></li></ul></li><li><a href="Config.html">Config</a><ul class='members'><li data-type='member'><a href="Config.html#baseDir">baseDir</a></li><li data-type='member'><a href="Config.html#bodyParser">bodyParser</a></li><li data-type='member'><a href="Config.html#cluster">cluster</a></li><li data-type='member'><a href="Config.html#confusedConfigurations">confusedConfigurations</a></li><li data-type='member'><a href="Config.html#development">development</a></li><li data-type='member'><a href="Config.html#dump">dump</a></li><li data-type='member'><a href="Config.html#env">env</a></li><li data-type='member'><a href="Config.html#HOME">HOME</a></li><li data-type='member'><a href="Config.html#hostHeaders">hostHeaders</a></li><li data-type='member'><a href="Config.html#httpclient">httpclient</a></li><li data-type='member'><a href="Config.html#i18n">i18n</a></li><li data-type='member'><a href="Config.html#ipHeaders">ipHeaders</a></li><li data-type='member'><a href="Config.html#jsonp">jsonp</a></li><li data-type='member'><a href="Config.html#keys">keys</a></li><li data-type='member'><a href="Config.html#logger">logger</a></li><li data-type='member'><a href="Config.html#logrotator">logrotator</a></li><li data-type='member'><a href="Config.html#meta">meta</a></li><li data-type='member'><a href="Config.html#middleware">middleware</a></li><li data-type='member'><a href="Config.html#multipart">multipart</a></li><li data-type='member'><a href="Config.html#name">name</a></li><li data-type='member'><a href="Config.html#notfound">notfound</a></li><li data-type='member'><a href="Config.html#onClientError">onClientError</a></li><li data-type='member'><a href="Config.html#pkg">pkg</a></li><li data-type='member'><a href="Config.html#protocolHeaders">protocolHeaders</a></li><li data-type='member'><a href="Config.html#proxy">proxy</a></li><li data-type='member'><a href="Config.html#rundir">rundir</a></li><li data-type='member'><a href="Config.html#security">security</a></li><li data-type='member'><a href="Config.html#siteFile">siteFile</a></li><li data-type='member'><a href="Config.html#static">static</a></li><li data-type='member'><a href="Config.html#view">view</a></li><li data-type='member'><a href="Config.html#watcher">watcher</a></li><li data-type='member'><a href="Config.html#.workerStartTimeout">workerStartTimeout</a></li></ul></li><li><a href="Context.html">Context</a><ul class='members'><li data-type='member'><a href="Context.html#accept">accept</a></li><li data-type='member'><a href="Context.html#acceptJSON">acceptJSON</a></li><li data-type='member'><a href="Context.html#coreLogger">coreLogger</a></li><li data-type='member'><a href="Context.html#helper">helper</a></li><li data-type='member'><a href="Context.html#ip">ip</a></li><li data-type='member'><a href="Context.html#locale">locale</a></li><li data-type='member'><a href="Context.html#locals">locals</a></li><li data-type='member'><a href="Context.html#logger">logger</a></li><li data-type='member'><a href="Context.html#params">params</a></li><li data-type='member'><a href="Context.html#queries">queries</a></li><li data-type='member'><a href="Context.html#realStatus">realStatus</a></li><li data-type='member'><a href="Context.html#router">router</a></li><li data-type='member'><a href="Context.html#starttime">starttime</a></li><li data-type='member'><a href="Context.html#view">view</a></li><li data-type='member'><a href="Context.html#__">__()</a></li><li data-type='member'><a href="Context.html#curl">curl()</a></li><li data-type='member'><a href="Context.html#getFileStream">getFileStream()</a></li><li data-type='member'><a href="Context.html#gettext">gettext()</a></li><li data-type='member'><a href="Context.html#multipart">multipart()</a></li><li data-type='member'><a href="Context.html#redirect">redirect()</a></li></ul></li><li><a href="ContextLoader.html">ContextLoader</a><ul class='members'><li data-type='member'><a href="ContextLoader.html#load">load()</a></li><li data-type='member'><a href="ContextLoader.html#parse">parse()</a></li></ul></li><li><a href="global.html#Controller">Controller</a><ul class='members'><li data-type='member'><a href="global.html#Controller#app">app</a></li><li data-type='member'><a href="global.html#Controller#config">config</a></li><li data-type='member'><a href="global.html#Controller#ctx">ctx</a></li><li data-type='member'><a href="global.html#Controller#service">service</a></li></ul></li><li><a href="EggApplication.html">EggApplication</a><ul class='members'><li data-type='member'><a href="EggApplication.html#BaseContextClass">BaseContextClass</a></li><li data-type='member'><a href="EggApplication.html#baseDir">baseDir</a></li><li data-type='member'><a href="EggApplication.html#config">config</a></li><li data-type='member'><a href="EggApplication.html#Controller">Controller</a></li><li data-type='member'><a href="EggApplication.html#coreLogger">coreLogger</a></li><li data-type='member'><a href="EggApplication.html#deprecate">deprecate</a></li><li data-type='member'><a href="EggApplication.html#env">env</a></li><li data-type='member'><a href="EggApplication.html#httpclient">httpclient</a></li><li data-type='member'><a href="EggApplication.html#loader">loader</a></li><li data-type='member'><a href="EggApplication.html#logger">logger</a></li><li data-type='member'><a href="EggApplication.html#loggers">loggers</a></li><li data-type='member'><a href="EggApplication.html#messenger">messenger</a></li><li data-type='member'><a href="EggApplication.html#name">name</a></li><li data-type='member'><a href="EggApplication.html#plugins">plugins</a></li><li data-type='member'><a href="EggApplication.html#proxy">proxy</a></li><li data-type='member'><a href="EggApplication.html#router">router</a></li><li data-type='member'><a href="EggApplication.html#Service">Service</a></li><li data-type='member'><a href="EggApplication.html#type">type</a></li><li data-type='member'><a href="EggApplication.html#addSingleton">addSingleton()</a></li><li data-type='member'><a href="EggApplication.html#beforeClose">beforeClose()</a></li><li data-type='member'><a href="EggApplication.html#beforeStart">beforeStart()</a></li><li data-type='member'><a href="EggApplication.html#close">close()</a></li><li data-type='member'><a href="EggApplication.html#cluster">cluster()</a></li><li data-type='member'><a href="EggApplication.html#curl">curl()</a></li><li data-type='member'><a href="EggApplication.html#getLogger">getLogger()</a></li><li data-type='member'><a href="EggApplication.html#inspect">inspect()</a></li><li data-type='member'><a href="EggApplication.html#toAsyncFunction">toAsyncFunction()</a></li><li data-type='member'><a href="EggApplication.html#toPromise">toPromise()</a></li><li data-type='member'><a href="EggApplication.html#url">url()</a></li><li data-type='member'><a href="EggApplication.html#use">use()</a></li></ul></li><li><a href="EggCore.html">EggCore</a><ul class='members'><li data-type='member'><a href="EggCore.html#BaseContextClass">BaseContextClass</a></li><li data-type='member'><a href="EggCore.html#baseDir">baseDir</a></li><li data-type='member'><a href="EggCore.html#config">config</a></li><li data-type='member'><a href="EggCore.html#Controller">Controller</a></li><li data-type='member'><a href="EggCore.html#deprecate">deprecate</a></li><li data-type='member'><a href="EggCore.html#loader">loader</a></li><li data-type='member'><a href="EggCore.html#name">name</a></li><li data-type='member'><a href="EggCore.html#plugins">plugins</a></li><li data-type='member'><a href="EggCore.html#router">router</a></li><li data-type='member'><a href="EggCore.html#Service">Service</a></li><li data-type='member'><a href="EggCore.html#type">type</a></li><li data-type='member'><a href="EggCore.html#beforeClose">beforeClose()</a></li><li data-type='member'><a href="EggCore.html#beforeStart">beforeStart()</a></li><li data-type='member'><a href="EggCore.html#close">close()</a></li><li data-type='member'><a href="EggCore.html#toAsyncFunction">toAsyncFunction()</a></li><li data-type='member'><a href="EggCore.html#toPromise">toPromise()</a></li><li data-type='member'><a href="EggCore.html#url">url()</a></li><li data-type='member'><a href="EggCore.html#use">use()</a></li></ul></li><li><a href="EggLoader.html">EggLoader</a><ul class='members'><li data-type='member'><a href="EggLoader.html#appInfo">appInfo</a></li><li data-type='member'><a href="EggLoader.html#ContextLoader">ContextLoader</a></li><li data-type='member'><a href="EggLoader.html#eggPaths">eggPaths</a></li><li data-type='member'><a href="EggLoader.html#FileLoader">FileLoader</a></li><li data-type='member'><a href="EggLoader.html#pkg">pkg</a></li><li data-type='member'><a href="EggLoader.html#plugins">plugins</a></li><li data-type='member'><a href="EggLoader.html#serverEnv">serverEnv</a></li><li data-type='member'><a href="EggLoader.html#serverScope">serverScope</a></li><li data-type='member'><a href="EggLoader.html#getAppInfo">getAppInfo()</a></li><li data-type='member'><a href="EggLoader.html#getHomedir">getHomedir()</a></li><li data-type='member'><a href="EggLoader.html#getLoadUnits">getLoadUnits()</a></li><li data-type='member'><a href="EggLoader.html#loadAgentExtend">loadAgentExtend()</a></li><li data-type='member'><a href="EggLoader.html#loadApplicationExtend">loadApplicationExtend()</a></li><li data-type='member'><a href="EggLoader.html#loadConfig">loadConfig()</a></li><li data-type='member'><a href="EggLoader.html#loadContextExtend">loadContextExtend()</a></li><li data-type='member'><a href="EggLoader.html#loadFile">loadFile()</a></li><li data-type='member'><a href="EggLoader.html#loadHelperExtend">loadHelperExtend()</a></li><li data-type='member'><a href="EggLoader.html#loadMiddleware">loadMiddleware()</a></li><li data-type='member'><a href="EggLoader.html#loadPlugin">loadPlugin()</a></li><li data-type='member'><a href="EggLoader.html#loadRequestExtend">loadRequestExtend()</a></li><li data-type='member'><a href="EggLoader.html#loadResponseExtend">loadResponseExtend()</a></li><li data-type='member'><a href="EggLoader.html#loadRouter">loadRouter()</a></li><li data-type='member'><a href="EggLoader.html#loadService">loadService()</a></li><li data-type='member'><a href="EggLoader.html#loadToApp">loadToApp()</a></li><li data-type='member'><a href="EggLoader.html#loadToContext">loadToContext()</a></li></ul></li><li><a href="FileLoader.html">FileLoader</a><ul class='members'><li data-type='member'><a href="FileLoader.html#load">load()</a></li><li data-type='member'><a href="FileLoader.html#parse">parse()</a></li></ul></li><li><a href="Helper.html">Helper</a><ul class='members'><li data-type='member'><a href="Helper.html#pathFor">pathFor()</a></li><li data-type='member'><a href="Helper.html#urlFor">urlFor()</a></li></ul></li><li><a href="I18n.html">I18n</a></li><li><a href="Messenger.html">Messenger</a><ul class='members'><li data-type='member'><a href="Messenger.html#broadcast">broadcast()</a></li><li data-type='member'><a href="Messenger.html#send">send()</a></li><li data-type='member'><a href="Messenger.html#sendRandom">sendRandom()</a></li><li data-type='member'><a href="Messenger.html#sendTo">sendTo()</a></li><li data-type='member'><a href="Messenger.html#sendToAgent">sendToAgent()</a></li><li data-type='member'><a href="Messenger.html#sendToApp">sendToApp()</a></li></ul></li><li><a href="Request.html">Request</a><ul class='members'><li data-type='member'><a href="Request.html#acceptJSON">acceptJSON</a></li><li data-type='member'><a href="Request.html#header">header</a></li><li data-type='member'><a href="Request.html#headers">headers</a></li><li data-type='member'><a href="Request.html#host">host</a></li><li data-type='member'><a href="Request.html#ip">ip</a></li><li data-type='member'><a href="Request.html#ips">ips</a></li><li data-type='member'><a href="Request.html#method">method</a></li><li data-type='member'><a href="Request.html#originalUrl">originalUrl</a></li><li data-type='member'><a href="Request.html#path">path</a></li><li data-type='member'><a href="Request.html#protocol">protocol</a></li><li data-type='member'><a href="Request.html#queries">queries</a></li><li data-type='member'><a href="Request.html#query">query</a></li><li data-type='member'><a href="Request.html#querystring">querystring</a></li><li data-type='member'><a href="Request.html#url">url</a></li><li data-type='member'><a href="Request.html#query">query()</a></li></ul></li><li><a href="Response.html">Response</a><ul class='members'><li data-type='member'><a href="Response.html#realStatus">realStatus</a></li><li data-type='member'><a href="Response.html#type">type</a></li><li data-type='member'><a href="Response.html#type">type</a></li></ul></li><li><a href="Router.html">Router</a><ul class='members'><li data-type='member'><a href="Router.html#register">register()</a></li><li data-type='member'><a href="Router.html#resources">resources()</a></li><li data-type='member'><a href="Router.html#url">url()</a></li></ul></li><li><a href="global.html#Service">Service</a><ul class='members'><li data-type='member'><a href="global.html#Service#app">app</a></li><li data-type='member'><a href="global.html#Service#config">config</a></li><li data-type='member'><a href="global.html#Service#ctx">ctx</a></li><li data-type='member'><a href="global.html#Service#service">service</a></li></ul></li></ul><h3>Namespaces</h3><ul><li><a href="Egg.html">Egg</a><ul class='members'><li data-type='member'><a href="Egg.html#Agent">Agent</a></li><li data-type='member'><a href="Egg.html#AgentWorkerLoader">AgentWorkerLoader</a></li><li data-type='member'><a href="Egg.html#Application">Application</a></li><li data-type='member'><a href="Egg.html#AppWorkerLoader">AppWorkerLoader</a></li><li data-type='member'><a href="Egg.html#BaseContextClass">BaseContextClass</a></li><li data-type='member'><a href="Egg.html#Controller">Controller</a></li><li data-type='member'><a href="Egg.html#Service">Service</a></li><li data-type='member'><a href="Egg.html#Subscription">Subscription</a></li></ul></li></ul>
</nav>

<div id="main">
    
    <h1 class="page-title">node_modules/egg-core/lib/egg.js</h1>
    

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>'use strict';

const assert = require('assert');
const fs = require('fs');
const KoaApplication = require('koa');
const EggConsoleLogger = require('egg-logger').EggConsoleLogger;
const debug = require('debug')('egg-core');
const is = require('is-type-of');
const co = require('co');
const BaseContextClass = require('./utils/base_context_class');
const utils = require('./utils');
const Router = require('./utils/router');
const Timing = require('./utils/timing');

const DEPRECATE = Symbol('EggCore#deprecate');
const CLOSESET = Symbol('EggCore#closeSet');
const ISCLOSE = Symbol('EggCore#isClose');
const CLOSE_PROMISE = Symbol('EggCore#closePromise');
const ROUTER = Symbol('EggCore#router');
const EGG_LOADER = Symbol.for('egg#loader');
const INIT_READY = Symbol('EggCore#initReady');


class EggCore extends KoaApplication {

  /**
   * @constructor
   * @param {Object} options - options
   * @param {String} [options.baseDir=process.cwd()] - the directory of application
   * @param {String} [options.type=application|agent] - whether it's running in app worker or agent worker
   * @param {Boolean} [options.typescript] - whether support typescript
   * @param {Object} [options.plugins] - custom plugins
   * @since 1.0.0
   */
  constructor(options = {}) {
    options.baseDir = options.baseDir || process.cwd();
    options.type = options.type || 'application';

    assert(typeof options.baseDir === 'string', 'options.baseDir required, and must be a string');
    assert(fs.existsSync(options.baseDir), `Directory ${options.baseDir} not exists`);
    assert(fs.statSync(options.baseDir).isDirectory(), `Directory ${options.baseDir} is not a directory`);
    assert(options.type === 'application' || options.type === 'agent', 'options.type should be application or agent');

    super();

    this.timing = new Timing();

    // register a close set
    this[CLOSESET] = new Set();
    // cache deprecate object by file
    this[DEPRECATE] = new Map();

    this[INIT_READY]();

    this.timing.start('Application Start');
    this.ready(() => this.timing.end('Application Start'));

    /**
     * @member {Object} EggCore#options
     * @private
     * @since 1.0.0
     */
    this._options = this.options = options;
    this.deprecate.property(this, '_options', 'app._options is deprecated, use app.options instead');

    /**
     * logging for EggCore, avoid using console directly
     * @member {Logger} EggCore#console
     * @private
     * @since 1.0.0
     */
    this.console = new EggConsoleLogger();

    /**
     * @member {BaseContextClass} EggCore#BaseContextClass
     * @since 1.0.0
     */
    this.BaseContextClass = BaseContextClass;

    /**
     * Base controller to be extended by controller in `app.controller`
     * @class Controller
     * @extends BaseContextClass
     * @example
     * class UserController extends app.Controller {}
     */
    const Controller = this.BaseContextClass;

    /**
     * Retrieve base controller
     * @member {Controller} EggCore#Controller
     * @since 1.0.0
     */
    this.Controller = Controller;

    /**
     * Base service to be extended by services in `app.service`
     * @class Service
     * @extends BaseContextClass
     * @example
     * class UserService extends app.Service {}
     */
    const Service = this.BaseContextClass;

    /**
     * Retrieve base service
     * @member {Service} EggCore#Service
     * @since 1.0.0
     */
    this.Service = Service;

    /**
     * The loader instance, the default class is {@link EggLoader}.
     * If you want define
     * @member {EggLoader} EggCore#loader
     * @since 1.0.0
     */
    const Loader = this[EGG_LOADER];
    assert(Loader, 'Symbol.for(\'egg#loader\') is required');
    this.loader = new Loader({
      baseDir: options.baseDir,
      app: this,
      plugins: options.plugins,
      typescript: options.typescript,
      logger: this.console,
      serverScope: options.serverScope,
    });
  }

  /**
   * override koa's app.use, support generator function
   * @param {Function} fn - middleware
   * @return {Application} app
   * @since 1.0.0
   */
  use(fn) {
    assert(is.function(fn), 'app.use() requires a function');
    debug('use %s', fn._name || fn.name || '-');
    this.middleware.push(utils.middleware(fn));
    return this;
  }

  /**
   * Whether `application` or `agent`
   * @member {String}
   * @since 1.0.0
   */
  get type() {
    return this.options.type;
  }

  /**
   * The current directory of application
   * @member {String}
   * @see {@link AppInfo#baseDir}
   * @since 1.0.0
   */
  get baseDir() {
    return this.options.baseDir;
  }

  /**
   * Alias to {@link https://npmjs.com/package/depd}
   * @member {Function}
   * @since 1.0.0
   */
  get deprecate() {
    const caller = utils.getCalleeFromStack();
    if (!this[DEPRECATE].has(caller)) {
      const deprecate = require('depd')('egg');
      // dynamic set _file to caller
      deprecate._file = caller;
      this[DEPRECATE].set(caller, deprecate);
    }
    return this[DEPRECATE].get(caller);
  }

  /**
   * The name of application
   * @member {String}
   * @see {@link AppInfo#name}
   * @since 1.0.0
   */
  get name() {
    return this.loader ? this.loader.pkg.name : '';
  }

  /**
   * Retrieve enabled plugins
   * @member {Object}
   * @since 1.0.0
   */
  get plugins() {
    return this.loader ? this.loader.plugins : {};
  }

  /**
   * The configuration of application
   * @member {Config}
   * @since 1.0.0
   */
  get config() {
    return this.loader ? this.loader.config : {};
  }

  /**
   * Execute scope after loaded and before app start
   *
   * @param  {Function|GeneratorFunction|AsyncFunction} scope function will execute before app start
   */
  beforeStart(scope) {
    if (!is.function(scope)) {
      throw new Error('beforeStart only support function');
    }

    // get filename from stack
    const name = utils.getCalleeFromStack(true);
    const timingkey = 'Before Start in ' + utils.getResolvedFilename(name, this.options.baseDir);

    this.timing.start(timingkey);

    const done = this.readyCallback(name);

    // ensure scope executes after load completed
    process.nextTick(() => {
      utils.callFn(scope).then(() => {
        done();
        this.timing.end(timingkey);
      }, err => {
        done(err);
        this.timing.end(timingkey);
      });
    });
  }

  /**
   * Close all, it wisll close
   * - callbacks registered by beforeClose
   * - emit `close` event
   * - remove add listeners
   *
   * If error is thrown when it's closing, the promise will reject.
   * It will also reject after following call.
   * @return {Promise} promise
   * @since 1.0.0
   */
  close() {
    if (this[CLOSE_PROMISE]) return this[CLOSE_PROMISE];

    const closeFunction = async () => {
      // close in reverse order: first created, last closed
      const closeFns = Array.from(this[CLOSESET]);
      for (const fn of closeFns.reverse()) {
        await utils.callFn(fn);
        this[CLOSESET].delete(fn);
      }
      // Be called after other close callbacks
      this.emit('close');
      this.removeAllListeners();
      this[ISCLOSE] = true;
    };
    this[CLOSE_PROMISE] = closeFunction();
    return this[CLOSE_PROMISE];
  }

  /**
   * Register a function that will be called when app close
   * @param {Function} fn - the function that can be generator function or async function
   */
  beforeClose(fn) {
    assert(is.function(fn), 'argument should be function');
    this[CLOSESET].add(fn);
  }

  /**
   * @member {Function}
   * @private
   */
  [INIT_READY]() {
    /**
     * register an callback function that will be invoked when application is ready.
     * @method {Function} EggCore#ready
     * @see https://github.com/node-modules/ready
     * @since 1.0.0
     * @example
     * const app = new Application(...);
     * app.ready(err => {
     *   if (err) throw err;
     *   console.log('done');
     * });
     */

    // get app timeout from env or use default timeout 10 second
    const eggReadyTimeoutEnv = Number.parseInt(process.env.EGG_READY_TIMEOUT_ENV || 10000);
    assert(Number.isInteger(eggReadyTimeoutEnv), `process.env.EGG_READY_TIMEOUT_ENV ${process.env.EGG_READY_TIMEOUT_ENV} should be able to parseInt.`);

    /**
     * If a client starts asynchronously, you can register `readyCallback`,
     * then the application will wait for the callback to ready
     *
     * It will log when the callback is not invoked after 10s
     *
     * Recommend to use {@link EggCore#beforeStart}
     * @method {Function} EggCore#readyCallback
     * @since 1.0.0
     * @example
     * const done = app.readyCallback('mysql');
     * mysql.ready(done);
     */
    require('ready-callback')({ timeout: eggReadyTimeoutEnv }).mixin(this);

    this.on('ready_stat', data => {
      this.console.info('[egg:core:ready_stat] end ready task %s, remain %j', data.id, data.remain);
    }).on('ready_timeout', id => {
      this.console.warn('[egg:core:ready_timeout] %s seconds later %s was still unable to finish.', eggReadyTimeoutEnv / 1000, id);
    });
  }

  /**
   * get router
   * @member {Router} EggCore#router
   * @since 1.0.0
   */
  get router() {
    if (this[ROUTER]) {
      return this[ROUTER];
    }
    const router = this[ROUTER] = new Router({ sensitive: true }, this);
    // register router middleware
    this.beforeStart(() => {
      this.use(router.middleware());
    });
    return router;
  }

  /**
   * Alias to {@link Router#url}
   * @param {String} name - Router name
   * @param {Object} params - more parameters
   * @return {String} url
   */
  url(name, params) {
    return this.router.url(name, params);
  }

  del(...args) {
    this.router.delete(...args);
    return this;
  }

  get [EGG_LOADER]() {
    return require('./loader/egg_loader');
  }

  /**
   * use co to wrap generator function to a function return promise
   * @param  {GeneratorFunction} fn input function
   * @return {AsyncFunction} async function return promise
   */
  toAsyncFunction(fn) {
    if (!is.generatorFunction(fn)) return fn;
    fn = co.wrap(fn);
    return async function(...args) {
      return fn.apply(this, args);
    };
  }

  /**
   * use co to wrap array or object to a promise
   * @param  {Mixed} obj input object
   * @return {Promise} promise
   */
  toPromise(obj) {
    return co(function* () {
      return yield obj;
    });
  }
}

// delegate all router method to application
utils.methods.concat([ 'all', 'resources', 'register', 'redirect' ]).forEach(method => {
  EggCore.prototype[method] = function(...args) {
    this.router[method](...args);
    return this;
  };
});

module.exports = EggCore;
</code></pre>
        </article>
    </section>




</div>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Thu Jun 07 2018 08:57:05 GMT+0000 (UTC) using the Minami theme.
</footer>

<script>prettyPrint();</script>
<script src="scripts/linenumber.js"></script>
</body>
</html>
